<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/11/3 0003
 * Time: 11:44
 */

namespace module;

use think\Db;
use think\log;
use library\Alisms;
use exception\ResponsableException;

class SmsApi
{

    /***以下短信类型  为sms_type 表主键id***/
    const SMS_TYPE_REGISTER = 1;//用户注册获取验证码时。
    const SMS_TYPE_LOGIN= 2;//用户登录获取验证码时。
    const SMS_TYPE_COMMON = 100;//通用验证码
    const SMS_TYPE_NEW_DEVICE_VERIFY = 102;//账户验证（新设备登陆） 新设备上用户首次用该设备登陆获取设备验证码时。
    const SMS_TYPE_NEW_DEVICE_LOGIN = 103;//账户验证（新设备登陆） 新设备上用户首次用登陆成功后。
    const SMS_TYPE_CHANGE_PASSWORD = 104;//修改密码
    private static $_smsCaptchaLength = 6; // 短信验证码长度(默认6位)
    private static $_smsCaptchaDayMax = 20; //短信验证码每天发送上限


    /**
     * 1@desc : 发送验证码短信接口
     * @param   : int $stId  sms_type 主键id
     * @param   : string $phone 手机号码
     * @param   : string $params 通知类短信需要多个参数
     */
    public static function send($stId, $phone, $uid = 0)
    {
        log::info("预备发送短信，用户{$uid}，手机号{$phone}，短信类型{$stId}" );
        try {
            //生成短信发送记录
            $data = self::getSmsTickets($stId, $phone, $uid);
            $tickets=self::smsCaptchaSend($data['sc_phone'], $data['sc_tickets'], $stId);
            self::updateSendStatus($data['sc_phone'],$tickets);
            log::info("短信发送结束，用户{$uid}，手机号{$phone}，短信类型{$stId}" );
            return $tickets;
        } catch (\Exception $e) {
            throw new ResponsableException($e->getMessage());
        }


    }

    /**
     * 生成短信记录
     * @param   : int $type 短信类型
     * @param   : string $phone 手机号码
     * @param   : string $params 通知类短信需要多个参数
     */
    public static function getSmsTickets($type, $phone, $uid = 0)
    {
        $ticket = \library\Helpers::randomString(32);
        if (config('SEND_SMS') != 1) {
            $code = '123456';
        } else {
            $code = self::_generateCaptcha(self::$_smsCaptchaLength);
        }
        $reslut = Db::table('sms_captcha')
            ->where('sc_phone', $phone)->where('sc_tickets', $ticket)->where('delete_flag', 1)->find();
        if (!$reslut) {
            $data = [
                'ui_id' => $uid,
                'st_id' => $type,
                'sc_code' => $code,
                'sc_phone' => $phone,
                'sc_created_at' => date('Y-m-d H:i:s'),
                'sc_status' => 1,
                'sc_tickets' => $ticket,
            ];
            $res = Db::table('sms_captcha')->insert($data);
            if (!$res) {
                throw new \Exception('数据库执行插入操作发生错误【smsCaptchaGenerate】');
            }
            return $data;
        }

    }


    /**
     * 发送短信验证码
     * @param   : int $scId 主键id
     * @param   : int $type 短信类型
     * @param   : string $phone 手机号码
     * @param   : string $code 验证码
     * @param   : string $params 通知类短信需要多个参数
     * @return bool true:发送成功|false:发送失败
     */
    public static function smsCaptchaSend($phone, $tickets, $stId)
    {
        //查询短信验证码模版
        $uid = Db::table('sms_captcha')->where('sc_phone', $phone)->where('sc_tickets', $tickets)->find();
        $smsType = self::getSmsType($stId);
        if (!$smsType) {
            throw new ResponsableException(null, ResponsableException::ERR_SMS_TYPE_TEMPLATE_MISSING);
        }

        if (config('SEND_SMS') == 1) {
           try {
                $array[$smsType['st_content']]=$uid['sc_code'];
                $bool = Alisms::send($phone, $smsType['st_code'],$array);
                if ($bool == false) {
                   throw new ResponsableException('短信发送失败');
                }
               return $tickets;
            } catch (\Exception $e) {
                throw new ResponsableException($e->getMessage());
            }

        } else {
            $res = Db::table('sms_captcha')->where('sc_id', $uid['sc_id'])->update(['sc_status' => 2, 'sc_updated_at' => date('Y-m-d H:i:s')]);
            return $tickets;
        }

    }

    //5.
    public static function updateSendStatus($phone,$tickets)
    {
      return  Db::table('sms_captcha')->where('sc_phone', $phone)->where('sc_tickets', $tickets)->update(['sc_status' => 3, 'sc_updated_at' => date('Y-m-d H:i:s')]);
    }

    /**
     * 获取短信验证码模板
     * @param string $stId sms_type 主键id
     * @return string 格式化的代码
     */
    public static function getSmsType($stId)
    {
        return Db::table('sms_type')->where('st_id', $stId)->where('delete_flag', 1)->find();
    }

    /**
     * 生成验证码方法
     * @param int $length 验证码长度
     * @param string $type 类别(默认:digital纯数字)
     * @return string 验证码
     */
    private static function _generateCaptcha($length, $type = 'digital')
    {
        $captcha = '';
        if ($type === 'digital') { // 纯数字验证码(默认)
            $captcha = rand(100000, 999999);;

        } else {
            // TODO 其他类型的验证码
        }
        return $captcha;
    }



    /**
     * 短信验证码是否正确
     * @param string $phone 手机号码
     *    * @param string $code 验证码
     * @param string $ticket 短信回执
     * @return boolean true:验证码正确|false:验证码错误
     * @throws \Exception
     */
    public static function smsCaptchaIsCorrect($phone,$code,$ticket)
    {
        return  Db::table('sms_captcha')->where('sc_phone', $phone)->where('sc_tickets', $ticket)->where('sc_status', 3)->where('sc_code',$code)->find();
    }



}